<!doctype html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />















  
  
  <link href="/blog/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/blog/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/blog/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="java,并发编程," />








  <link rel="shortcut icon" type="image/x-icon" href="/blog/favicon.ico?v=5.1.0" />






<meta name="description" content="CPU缓存一致性为了解决CPU处理速度与内存读取速度之间的差异，现代计算机设计引入了CPU高速缓存（L1,L2缓存）。提高了CPU的利用率。随即又产生了另一个问题：多个CPU之间缓存一致性的问题。如果只有一个CPU时，则不存在缓存一致性的问题。当存在多个CPU，且同时引用同一块相同的内存地址时，可能出现缓存一致性问题。解决缓存一致性的问题大致有两种方法  通过在总线加LOCK#锁的方式在早期CPU">
<meta name="keywords" content="java,并发编程">
<meta property="og:type" content="article">
<meta property="og:title" content="CPU缓存一致性协议MESI">
<meta property="og:url" content="https://gitee.com/shuhao/2018/08/01/CPU缓存一致性协议/index.html">
<meta property="og:site_name" content="Niki">
<meta property="og:description" content="CPU缓存一致性为了解决CPU处理速度与内存读取速度之间的差异，现代计算机设计引入了CPU高速缓存（L1,L2缓存）。提高了CPU的利用率。随即又产生了另一个问题：多个CPU之间缓存一致性的问题。如果只有一个CPU时，则不存在缓存一致性的问题。当存在多个CPU，且同时引用同一块相同的内存地址时，可能出现缓存一致性问题。解决缓存一致性的问题大致有两种方法  通过在总线加LOCK#锁的方式在早期CPU">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://gitee.com/blog/images/computer/MESI_1.jpg">
<meta property="og:image" content="https://gitee.com/blog/images/computer/smp.png">
<meta property="og:image" content="https://gitee.com/blog/images/computer/numa.png">
<meta property="og:updated_time" content="2018-08-24T02:15:50.898Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="CPU缓存一致性协议MESI">
<meta name="twitter:description" content="CPU缓存一致性为了解决CPU处理速度与内存读取速度之间的差异，现代计算机设计引入了CPU高速缓存（L1,L2缓存）。提高了CPU的利用率。随即又产生了另一个问题：多个CPU之间缓存一致性的问题。如果只有一个CPU时，则不存在缓存一致性的问题。当存在多个CPU，且同时引用同一块相同的内存地址时，可能出现缓存一致性问题。解决缓存一致性的问题大致有两种方法  通过在总线加LOCK#锁的方式在早期CPU">
<meta name="twitter:image" content="https://gitee.com/blog/images/computer/MESI_1.jpg">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/blog/',
    scheme: 'Mist',
    sidebar: {"position":"right","display":"post","offset":12,"offset_float":0,"b2t":false,"scrollpercent":false},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://gitee.com/shuhao/2018/08/01/CPU缓存一致性协议/"/>





  <title> CPU缓存一致性协议MESI | Niki </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  





  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?cb9f0585e406f878cb2f29c89ad3cdb7";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>










  
  
    
  

  <div class="container one-collumn sidebar-position-right page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/blog/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Niki</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">天道酬勤</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/blog/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-categories"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/blog/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
    <link itemprop="mainEntityOfPage" href="https://gitee.com/shuhao/blog/2018/08/01/CPU缓存一致性协议/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Fang ShuHao">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/head.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Niki">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                CPU缓存一致性协议MESI
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-08-01T09:23:00+08:00">
                2018-08-01
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <h2 id="CPU缓存一致性"><a href="#CPU缓存一致性" class="headerlink" title="CPU缓存一致性"></a>CPU缓存一致性</h2><p>为了解决CPU处理速度与内存读取速度之间的差异，现代计算机设计引入了CPU高速缓存（L1,L2缓存）。提高了CPU的利用率。随即又产生了另一个问题：多个CPU之间缓存一致性的问题。<br>如果只有一个CPU时，则不存在缓存一致性的问题。当存在多个CPU，且同时引用同一块相同的内存地址时，可能出现缓存一致性问题。解决缓存一致性的问题大致有两种方法</p>
<ol>
<li><p>通过在总线加LOCK#锁的方式<br>在早期CPU中采用这种方式。当一个CPU修改共享的内存时，会在消息总线上加上LOCK#锁，那么其他的CPU则无法访问总线，当操作结束后，因为LOCK#的原因，其他CPU会访问主内存，刷新自己的缓存。从而保证了内存一致性。<br>这种处理方式的一个缺点就是：当有一个CPU修改内存变量时，会LOCK消息总线，导致其他CPU都无法访问消息总线。</p>
</li>
<li><p>通过缓存一致性协议<br>为了解决LOCK消息总线，其他CPU无法访问消息总线的问题，有引入了一种新的解决缓存一致性的技术：缓存一致性协议。而MESI协议则是其中比较著名的一个。</p>
</li>
</ol>
<h2 id="MESI协议"><a href="#MESI协议" class="headerlink" title="MESI协议"></a>MESI协议</h2><p>MESI协议是一种广泛使用的支持<strong>回写策略</strong>的<strong>缓存一致性</strong>协议。<br>每个CPU为了会集成一个L1高速缓存，主要是用来平衡cpu处理速度与读取主内存速度的差别，尽可能发挥CPU的处理效率。那么每个CPU中的L1缓存与主内存数据的一致性问题就需要解决，MESI协议就是其中解决方式之一。<br>该协议被应用于Intel奔腾系列的CPU中。</p>
<p>MESI协议由M（Modify）、E(Exclusive)、S(Share)、I(Invalid)四种状态组成；来标记CPU缓存行（cache line）的状态</p>
<h3 id="被修改-Modify"><a href="#被修改-Modify" class="headerlink" title="被修改 Modify"></a>被修改 Modify</h3><p>当缓存的内容被修改时，持有该内容的CPU缓存内状态为Modify， 并且需要将其修改的内容写回主内存，随后该缓存状态变为Exclusive。</p>
<h3 id="独占-Exclusive"><a href="#独占-Exclusive" class="headerlink" title="独占 Exclusive"></a>独占 Exclusive</h3><p>该 状态只被缓存在CPU缓存中，并且缓存的内容与主内存内容一致。当有其他CPU读取主内存中内容时，会变成Share状态。当有CPU修改缓存中的内容时，该状态又会修改为Modify</p>
<h3 id="共享-Share"><a href="#共享-Share" class="headerlink" title="共享 Share"></a>共享 Share</h3><p>当一个内存变量被多个CPU缓存，并且缓存内容与主内存内容一致。此时状态为Share。当有一个CPU修改缓存内容时，其他所有CPU缓存的内容状态修改为Invalid</p>
<h3 id="失效-Invalid"><a href="#失效-Invalid" class="headerlink" title="失效 Invalid"></a>失效 Invalid</h3><p>当有一个CPU修其缓存的内容时，其他CPU中缓存的内容状态修改为Invalid</p>
<p>注：在判断CPU缓存行处于MESI那个状态，关键在于：本地CPU读取，本地CPU写， 其他CPU读，其他CPU写。</p>
<ol>
<li>CPU缓存内容与主内存保存内容差别</li>
<li>CPU缓存内容与其他CPU缓存内容关系（是否自身修改，是否其他CPU修改）</li>
</ol>
<p><strong>缓存行状态转换图</strong><br><img src="/blog/images/computer/MESI_1.jpg"></p>
<h2 id="SMP结构与NUMA-结构"><a href="#SMP结构与NUMA-结构" class="headerlink" title="SMP结构与NUMA 结构"></a>SMP结构与NUMA 结构</h2><p>为了处理CPU与存储器之间的联系也有很多解决方案如：SMP接口和NUMA接口</p>
<h3 id="SMP结构"><a href="#SMP结构" class="headerlink" title="SMP结构"></a>SMP结构</h3><p>(Symmetric Multi-Procesor) 这种结构中，CPU与存储器之间采用总线互联的方式，处理器和存储器都有负责发送和监听总线广播的信息的总线控制单元。但是<strong>同一时刻只能有一个处理器（存储控制器）在总线上广播，所有的处理器都可以监听</strong><br><img src="/blog/images/computer/smp.png"><br>对SMP服务器来讲最受限制的是内存，内个CPU通过相同的总线访问相同的内存资源。随着CPU的增加，内存访问冲突迅速增加。最终造成CPU资源的浪费。CPU性能大大降低</p>
<h3 id="NUMA结构"><a href="#NUMA结构" class="headerlink" title="NUMA结构"></a>NUMA结构</h3><p>为了解决SMP扩展能力的限制，产生了NUMA结构（Non-Uniform Memory Access）。<br>这种结构中，每个CPU与一块本地内存构成一个模块，并且与其他cpu构成的这种模块相连接，形成一个小型的网络。CPU读取自身的本地内存速度较快，但是读取其他CPU内存比较慢，因为通过互联网络会产生延时。<br><img src="/blog/images/computer/numa.png"></p>
<h2 id="MESI协议在SMP结构中运用"><a href="#MESI协议在SMP结构中运用" class="headerlink" title="MESI协议在SMP结构中运用"></a>MESI协议在SMP结构中运用</h2><p>因为SMP结构中，多个CPU与一个主内存中的内容需要进行内容的同步，所以，这种结构的处理器中，也采用MESI协议来处理一致性问题。通过MESI协议来保证每个CPU缓存中的数据与主内存数据一致，并且保证每个CPU对主内存的修改对其他CPU是可见的。</p>
<h2 id="volatile"><a href="#volatile" class="headerlink" title="volatile"></a>volatile</h2><p>在线程安全中心，volatile关键字修饰的变量能够保证在多个线程中数据的可见性与有序性。。即一个线程修改了数据后其他线程能够收到通知，并刷新线程自身的缓存；并且能够避免编译重排序，指令重排序的影响。<br>volatile实现的原理主要通过内存屏障实现的。</p>
<ul>
<li>在<strong>读操作之前</strong>加上内存屏障，则会导致读取操作刷新缓存，去主内存读取数据</li>
<li>在<strong>写操作之后</strong>加上内存屏障，会是其他CPU缓存的变量无效，从而去主内存中重新加载</li>
<li>内存屏障也保证了程序不受重排序的影响</li>
</ul>
<blockquote>
<blockquote>
<p>参考<br><a href="https://blog.csdn.net/realxie/article/details/7317630" target="_blank" rel="external">MESI-CPU缓存一致性协议</a><br><a href="https://blog.csdn.net/iter_zc/article/details/40342695" target="_blank" rel="external">缓存一致性对并发的影响</a><br><a href="https://blog.csdn.net/gatieme/article/details/52098615" target="_blank" rel="external">服务体系与共享架构</a></p>
</blockquote>
</blockquote>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>


    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/blog/tags/java/" rel="tag"># java</a>
          
            <a href="/blog/tags/并发编程/" rel="tag"># 并发编程</a>
          
        </div>
      

      
        
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/blog/2018/07/10/jenkins安装采坑记/" rel="next" title="jenkins安装采坑记">
                <i class="fa fa-chevron-left"></i> jenkins安装采坑记
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/blog/2018/08/21/Maven之Dependencies与DependencyManagement/" rel="prev" title="Maven之Dependencies与DependencyManagement">
                Maven之Dependencies与DependencyManagement <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>

          
          </div>
          


          
  <div class="comments" id="comments">
    
      <div id="lv-container" data-id="city" data-uid="MTAyMC8zNjY5NS8xMzIzMA=="></div>
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/blog/images/head.jpg"
               alt="Fang ShuHao" />
          <p class="site-author-name" itemprop="name">Fang ShuHao</p>
           
              <p class="site-description motion-element" itemprop="description"></p>
          
        </div>
        <nav class="site-state motion-element">
        
          
            <div class="site-state-item site-state-posts">
              <a href="/blog/archives">
                <span class="site-state-item-count">135</span>
                <span class="site-state-item-name">日志</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-categories">
              <a href="/blog/categories">
                <span class="site-state-item-count">35</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/blog/tags">
                <span class="site-state-item-count">93</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
        </div>

        
        

        
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#CPU缓存一致性"><span class="nav-number">1.</span> <span class="nav-text">CPU缓存一致性</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#MESI协议"><span class="nav-number">2.</span> <span class="nav-text">MESI协议</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#被修改-Modify"><span class="nav-number">2.1.</span> <span class="nav-text">被修改 Modify</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#独占-Exclusive"><span class="nav-number">2.2.</span> <span class="nav-text">独占 Exclusive</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#共享-Share"><span class="nav-number">2.3.</span> <span class="nav-text">共享 Share</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#失效-Invalid"><span class="nav-number">2.4.</span> <span class="nav-text">失效 Invalid</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#SMP结构与NUMA-结构"><span class="nav-number">3.</span> <span class="nav-text">SMP结构与NUMA 结构</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#SMP结构"><span class="nav-number">3.1.</span> <span class="nav-text">SMP结构</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#NUMA结构"><span class="nav-number">3.2.</span> <span class="nav-text">NUMA结构</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#MESI协议在SMP结构中运用"><span class="nav-number">4.</span> <span class="nav-text">MESI协议在SMP结构中运用</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#volatile"><span class="nav-number">5.</span> <span class="nav-text">volatile</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2019</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Fang ShuHao</span>
</div>


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Mist
  </a>
</div>


        

        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    
    
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  




  
  <script type="text/javascript" src="/blog/lib/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/blog/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/blog/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/blog/lib/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/blog/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/blog/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/blog/js/src/utils.js?v=5.1.0"></script>

  <script type="text/javascript" src="/blog/js/src/motion.js?v=5.1.0"></script>



  
  

  
  <script type="text/javascript" src="/blog/js/src/scrollspy.js?v=5.1.0"></script>
<script type="text/javascript" src="/blog/js/src/post-details.js?v=5.1.0"></script>



  


  <script type="text/javascript" src="/blog/js/src/bootstrap.js?v=5.1.0"></script>



  



  




	





  





  





  
    <script type="text/javascript">
      (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
      })(document, 'script');
    </script>
  



  
  

  

  

  

  


  

</body>
</html>
